package node.exp;

import grammar.Lexer;
import lexical.Key;
import midcode.MidCode;
import midcode.MidcodeGenerator;
import midcode.OPType;
import node.Node;
import symbol.SymbolTable;

import java.util.ArrayList;

public class LAndExp implements Node {
    private final Lexer lexer;
    private final SymbolTable table;
    private final Node father;
    public ArrayList<EqExp> eqExps = new ArrayList<>();

    public LAndExp(Lexer lexer, SymbolTable table, Node father) {
        this.lexer = lexer;
        this.table = table;
        this.father = father;
        parseLAndExp();
    }

    private void parseLAndExp() {
        eqExps.add(new EqExp(lexer, table, this));
        while (lexer.isWordType(0, Key.AND)) {
            lexer.getCurWord(); // &&
            eqExps.add(new EqExp(lexer, table, this));
        }
    }

    @Override
    public Node getFather() {
        return father;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(eqExps.get(0).toString());
        for (int i = 1; i < eqExps.size(); i++) {
            sb.append("AND &&\n").append(eqExps.get(i).toString()).append("<LAndExp>\n");
        }
        return sb.toString();
    }

    public String genMidCode(boolean isLast, String label, String opLabel) {
        MidcodeGenerator mg = MidcodeGenerator.getInstance();
        if (isLast) {
            if (opLabel == null) {
                for (EqExp eqExp : eqExps) {
                    String tmp = eqExp.genMidCode();
                    mg.addMidcode(new MidCode(OPType.BEQ, tmp, "0", label));
                }
            } else {
                for (EqExp eqExp : eqExps) {
                    String tmp = eqExp.genMidCode();
                    if (eqExp == eqExps.get(eqExps.size() - 1)) {
                        mg.addMidcode(new MidCode(OPType.BNE, tmp, "0", opLabel));
                    } else {
                        mg.addMidcode(new MidCode(OPType.BEQ, tmp, "0", label));
                    }
                }
            }
        } else {
            String blockLabel = mg.genLabel();
            for (EqExp eqExp : eqExps) {
                String tmp = eqExp.genMidCode();
                if (eqExp == eqExps.get(eqExps.size() - 1)) {
                    mg.addMidcode(new MidCode(OPType.BNE, tmp, "0", label));
                } else {
                    mg.addMidcode(new MidCode(OPType.BEQ, tmp, "0", blockLabel));
                }
            }
            mg.addMidcode(new MidCode(OPType.LABEL_GEN, null, null, blockLabel));
        }
        return "";
    }

    @Override
    public String genMidCode() {
        return "";
    }
}

